﻿#include "guild_service_welfare_context.h"

#include "GuildRedEnvelopeBrief_struct.h"

#include "NewGuildRedEnvelopeNtfData_struct.h"
#include "guildservicewelfare/LoginArg_struct.h"
#include "guildservicewelfare/LoginRes_struct.h"
#include "GrabGuildRedEnvelopeArg_struct.h"
#include "GrabGuildRedEnvelopeRes_struct.h"
#include "SendGuildRedEnvelopeArg_struct.h"
#include "SendGuildRedEnvelopeRes_struct.h"
#include "SetGuildAuctionAttentionArg_struct.h"
#include "SetGuildAuctionAttentionRes_struct.h"
#include "SetGuildAuctionOfferArg_struct.h"
#include "SetGuildAuctionOfferRes_struct.h"
#include "AddGuildRepositoryCellItemArg_struct.h"
#include "AddGuildRepositoryCellItemRes_struct.h"
#include "DelGuildRepositoryCellItemArg_struct.h"
#include "DelGuildRepositoryCellItemRes_struct.h"
#include "GetGuildWelfareAwardArg_struct.h"
#include "GetGuildWelfareAwardRes_struct.h"

#include "LogoutNtfData_struct.h"
#include "box/service_context.hh"
#include "error/make_error_code.h"
#include "fwd.h"
#include "guild/guild.h"
#include "guildservicewelfare.enum.h"

#include "logic/guild_red_envelope_logic.h"
#include "logic/guild_repository_logic.h"
#include "logic/guild_members_logic.h"

#include "proxy/guild_service_welfare_proxy_mgr.h"
#include "token/service_token_mgr.hpp"


namespace guild_service {
bool GuildServiceWelfareContext::Start(
    kratos::service::ServiceContext *context) {
  if (!GuildServiceWelfareContext::Init(context)) {
    LOG_FAIL("公会福利服务启动失败");
    return false;
  }

  return register_service(std::string(kGuildServicePrefix) +
                          std::string(kGuildServiceWelfareName));
}

bool GuildServiceWelfareContext::Stop() {
  LOG_INFO("公会福利服务关闭");

  if (!unregister_service(std::string(kGuildServicePrefix) +
                          std::string(kGuildServiceWelfareName))) {
    LOG_FAIL("公会福利服务关闭失败");
    return false;
  }

  return GuildServiceWelfareContext::Uninit();
}

bool GuildServiceWelfareContext::Init(
    kratos::service::ServiceContext *context) {
  if (!common::singleton_start<common::service_logger>(
          context, kGuildServiceWelfareName)) {
    return false;
  }

  LOG_INFO("公会福利服务启动");

  if (!common::singleton_start<common::service_context>(context)) {
    LOG_FAIL("公会福利服务启动失败");
    return false;
  }

  if (!common::singleton_start<common::service_redis_client>(context)) {
    LOG_FAIL("公会福利服务启动失败");
    return false;
  }

  if (!redis_add_host(kGuildServiceWelfareName, kRedisHost, kRedisPort,
                      kRedisUser, kRedisPasswd)) {
    LOG_FAIL("公会福利服务启动失败");
    return false;
  }

  if (!common::singleton_start<common::util>(context)) {
    LOG_FAIL("公会福利服务启动失败");
    return false;
  }

  if (!common::singleton_start<common::service_time_scheduler>(context)) {
    LOG_FAIL("公会福利服务启动失败");
    return false;
  }

  return true;
}

bool GuildServiceWelfareContext::Uninit() {
  return common::singleton_stop<common::service_time_scheduler>() &&
         common::singleton_stop<common::service_redis_client>() &&
         common::singleton_stop<common::util>() &&
         common::singleton_stop<common::service_context>() &&
         common::singleton_stop<common::service_logger>();
}

void GuildServiceWelfareContext::Tick(time_t ms) {
  common::singleton_update<common::service_redis_client>(ms);
  common::singleton_update<common::service_time_scheduler>(ms);
}

void GuildServiceWelfareContext::SendGuildRedEnvelope(rpc::StubCallPtr call,
    const SendGuildRedEnvelopeArg &arg,
    std::shared_ptr<SendGuildRedEnvelopeRes> &res) {
  token_type token = detail::GetToken(call);
#ifdef DEBUG
  token = arg.token;
#endif

  if (token == kInvalidToken) {
    res->result = ErrorCode::ERR_INVALID_TOKEN;
    return;
  }

  role_uuid_type role_uuid =
      detail::GetRoleUuid(kGuildServiceWelfareName, token);
  if (role_uuid == kInvalidRoleUuid) {
    res->result = ErrorCode::ERR_INVALID_ROLE_UUID;
    return;
  }
  error_code ec(ErrorCode::ERR_SUCCESS);

  try {
    if (!GuildModuleRedEnvelopeLogic::SendGuildRedEnvelope(
            role_uuid, arg.brief, arg.passwd, res->red_envelope_uid, ec)) {
      LOG_WARN("发送公会红包失败 角色唯一id:%llu 错误:%s",
               arg.brief.sender_role_uuid, ec.message().c_str());
      res->result = static_cast<ErrorCode>(ec.value());
      return;
    }
  } catch (std::exception &ex) {
    LOG_EXCEPT("发送公会红包异常 异常:%s", ex.what());
    return;
  }

  res->result = static_cast<ErrorCode>(ec.value());

  // 发送新红包通知
  if (res->result == ErrorCode::ERR_SUCCESS) {
    NewGuildRedEnvelopeNtfData data;
    data.brief = arg.brief;
    data.uid = res->red_envelope_uid;

    GuildServiceWelfareProxyMgrSingleton->ForeachProxy(
        [&data](const role_uuid_type role_uuid,
                const std::shared_ptr<GuildClientWelfareProxy> proxy_ptr) {
          proxy_ptr->NewGuildRedEnvelopeNtf(data);
        });
  }
}

void GuildServiceWelfareContext::GrabGuildRedEnvelope(rpc::StubCallPtr call,
    const GrabGuildRedEnvelopeArg &arg,
    const std::shared_ptr<GrabGuildRedEnvelopeRes> &res) {
  token_type token = detail::GetToken(call);
#ifdef DEBUG
  token = arg.token;
#endif

  if (token == kInvalidToken) {
    res->result = ErrorCode::ERR_INVALID_TOKEN;
    return;
  }

  role_uuid_type role_uuid =
      detail::GetRoleUuid(kGuildServiceWelfareName, token);
  if (role_uuid == kInvalidRoleUuid) {
    res->result = ErrorCode::ERR_INVALID_ROLE_UUID;
    return;
  }
  error_code ec(ErrorCode::ERR_SUCCESS);

  try {
    if (!GuildModuleRedEnvelopeLogic::GrabGuildRedEnvelope(
            role_uuid, arg.red_envelope_uid, res->brief, res->grabber_list,
            ec)) {
      LOG_WARN("抢公会红包失败 玩家凭证:%u 错误:%s", arg.token,
               ec.message().c_str());
      res->result = static_cast<ErrorCode>(ec.value());
      return;
    }
  } catch (std::exception &ex) {
    LOG_EXCEPT("抢公会红包异常 异常:%s", ex.what());
    return;
  }

  res->result = static_cast<ErrorCode>(ec.value());
}

void GuildServiceWelfareContext::Login(
    rpc::StubCallPtr call, const LoginArg &arg,
    const std::shared_ptr<LoginRes> &res) {
  token_type token = detail::GetToken(call);
#ifdef DEBUG
  token = arg.token;
#endif

  if (token == kInvalidToken) {
    res->result = ErrorCode::ERR_INVALID_TOKEN;
    return;
  }

  role_uuid_type role_uuid =
      detail::GetRoleUuid(kGuildServiceWelfareName, token);
  if (role_uuid == kInvalidRoleUuid) {
    res->result = ErrorCode::ERR_INVALID_ROLE_UUID;
    return;
  }

  if (!GuildServiceWelfareProxyMgrSingleton->Login(call, role_uuid)) {
    res->result = ErrorCode::ERR_FAILED;
    return;
  }

  res->result = ErrorCode::ERR_SUCCESS;
}

void GuildServiceWelfareContext::Logout(rpc::StubCallPtr call, const LogoutNtfData &data) {
  role_uuid_type role_uuid = kInvalidRoleUuid;
  ServiceTokenMgrSingleton().GetRoleUuid(kGuildServiceWelfareName, detail::GetToken(call), role_uuid);
  if (role_uuid == kInvalidRoleUuid) {
    return;
  }

  GuildServiceWelfareProxyMgrSingleton->Logout(role_uuid);
}

void GuildServiceWelfareContext::SetGuildAuctionOffer(rpc::StubCallPtr call, 
    const SetGuildAuctionOfferArg &arg,
    const std::shared_ptr<SetGuildAuctionOfferRes> &res) {
  token_type token = detail::GetToken(call);
#ifdef DEBUG
  token = arg.token;
#endif

  if (token == kInvalidToken) {
    res->result = ErrorCode::ERR_INVALID_TOKEN;
    return;
  }

  role_uuid_type role_uuid =
      detail::GetRoleUuid(kGuildServiceWelfareName, token);
  if (role_uuid == kInvalidRoleUuid) {
    res->result = ErrorCode::ERR_INVALID_ROLE_UUID;
    return;
  }
  error_code ec(ErrorCode::ERR_SUCCESS);

  try {
    if (!GuildModuleRepositoryLogic::SetGuildAuctionOffer(
            role_uuid, arg.item_uuid, arg.offer, res->old_offer, ec)) {
      LOG_WARN("设置拍卖价格失败 玩家凭证:%u 错误:%s", arg.token,
               ec.message().c_str());

      res->result = static_cast<ErrorCode>(ec.value());
      return;
    }
  } catch (std::exception &ex) {
    LOG_EXCEPT("设置拍卖价格异常 异常:%s", ex.what());
    return;
  }

  res->result = static_cast<ErrorCode>(ec.value());
}

void GuildServiceWelfareContext::SetGuildAuctionAttention(rpc::StubCallPtr call, 
    const SetGuildAuctionAttentionArg &arg,
    const std::shared_ptr<SetGuildAuctionAttentionRes> &res) {
  token_type token = detail::GetToken(call);
#ifdef DEBUG
  token = arg.token;
#endif

  if (token == kInvalidToken) {
    res->result = ErrorCode::ERR_INVALID_TOKEN;
    return;
  }

  role_uuid_type role_uuid =
      detail::GetRoleUuid(kGuildServiceWelfareName, token);
  if (role_uuid == kInvalidRoleUuid) {
    res->result = ErrorCode::ERR_INVALID_ROLE_UUID;
    return;
  }
  error_code ec(ErrorCode::ERR_SUCCESS);

  try {
    if (!GuildModuleRepositoryLogic::SetGuildAuctionAttention(
            role_uuid, arg.item_uuid, arg.is_attention, ec)) {
      LOG_WARN("设置拍卖关注失败 玩家凭证:%u 错误:%s", arg.token,
               ec.message().c_str());
      res->result = static_cast<ErrorCode>(ec.value());
      return;
    }
  } catch (std::exception &ex) {
    LOG_EXCEPT("设置拍卖关注异常 异常:%s", ex.what());
    return;
  }

  res->result = static_cast<ErrorCode>(ec.value());
}

void GuildServiceWelfareContext::AddGuildRepositoryCellItem(rpc::StubCallPtr call, 
    const AddGuildRepositoryCellItemArg &arg,
    std::shared_ptr<AddGuildRepositoryCellItemRes> &res) {
  token_type token = detail::GetToken(call);
#ifdef DEBUG
  token = arg.token;
#endif

  if (token == kInvalidToken) {
    res->result = ErrorCode::ERR_INVALID_TOKEN;
    return;
  }

  role_uuid_type role_uuid =
      detail::GetRoleUuid(kGuildServiceWelfareName, token);
  if (role_uuid == kInvalidRoleUuid) {
    res->result = ErrorCode::ERR_INVALID_ROLE_UUID;
    return;
  }
  error_code ec(ErrorCode::ERR_SUCCESS);

  try {
    if (!GuildModuleRepositoryLogic::AddGuildRepositoryCellItem(
            role_uuid, arg.item_id, ec)) {
      LOG_WARN("添加仓库道具失败 玩家凭证:%u 错误:%s", arg.token,
               ec.message().c_str());
      res->result = static_cast<ErrorCode>(ec.value());
      return;
    }
  } catch (std::exception &ex) {
    LOG_EXCEPT("添加仓库道具异常 异常:%s", ex.what());
    return;
  }

  res->result = static_cast<ErrorCode>(ec.value());
}

void GuildServiceWelfareContext::DelGuildRepositoryCellItem(rpc::StubCallPtr call, 
    const DelGuildRepositoryCellItemArg &arg,
    std::shared_ptr<DelGuildRepositoryCellItemRes> &res) {
  token_type token = detail::GetToken(call);
#ifdef DEBUG
  token = arg.token;
#endif

  if (token == kInvalidToken) {
    res->result = ErrorCode::ERR_INVALID_TOKEN;
    return;
  }

  role_uuid_type role_uuid =
      detail::GetRoleUuid(kGuildServiceWelfareName, token);
  if (role_uuid == kInvalidRoleUuid) {
    res->result = ErrorCode::ERR_INVALID_ROLE_UUID;
    return;
  }
  error_code ec(ErrorCode::ERR_SUCCESS);

  try {
    if (!GuildModuleRepositoryLogic::DelGuildRepositoryCellItem(
            role_uuid, arg.item_uuid, ec)) {
      LOG_WARN("删除仓库道具失败 玩家凭证:%u 错误:%s", arg.token,
               ec.message().c_str());
      res->result = static_cast<ErrorCode>(ec.value());
      return;
    }
  } catch (std::exception &ex) {
    LOG_EXCEPT("删除拍卖关注异常 异常:%s", ex.what());
    return;
  }

  res->result = static_cast<ErrorCode>(ec.value());
}
void GuildServiceWelfareContext::GetGuildWelfareAward(
    rpc::StubCallPtr call, const GetGuildWelfareAwardArg &arg,
    std::shared_ptr<GetGuildWelfareAwardRes> &res) {
  token_type token = detail::GetToken(call);
#ifdef DEBUG
  token = arg.token;
#endif

  if (token == kInvalidToken) {
    res->result = ErrorCode::ERR_INVALID_TOKEN;
    return;
  }

  role_uuid_type role_uuid =
      detail::GetRoleUuid(kGuildServiceWelfareName, token);
  if (role_uuid == kInvalidRoleUuid) {
    res->result = ErrorCode::ERR_INVALID_ROLE_UUID;
    return;
  }
  error_code ec(ErrorCode::ERR_SUCCESS);

  try {
    if (!GuildMembersLogic::GetGuildWelfareAward(role_uuid, ec)) {
      LOG_WARN("获取公会福利奖励 玩家凭证:%u 错误:%s", arg.token,
               ec.message().c_str());
      res->result = static_cast<ErrorCode>(ec.value());
      return;
    }
  } catch (std::exception &ex) {
    LOG_EXCEPT("获取公会福利奖励异常 异常:%s", ex.what());
    return;
  }

  res->result = static_cast<ErrorCode>(ec.value());
}

};  // namespace guild_service